/**
********************************************************************************
* @file     main.c
* @brief    对文件的简要说明
* @details  对文件的详细说明
* @author   jcai
* @date     2024-05-28 10:57:10
* @copyright Copyright &copy; 2024 wy1107412334@163.com All rights reserved
* @version  v0.0.1
*
* \n Email:  wy1107412334@163.com
* \n Blog:   None
* \n Github: https://github.com/wy1107412334
* \n Gitee:  https://gitee.com/git.git1107412334.com
*
********************************************************************************
* @note
* None.
********************************************************************************
* @attention
* None.
********************************************************************************
@verbatim
@endverbatim
********************************************************************************
* @par 历史记录
* jcai, 2024-05-28 10:57:10
* - 首次编写
*
*<center>Copyright &copy; 2024 wy1107412334@163.com All rights reserved</center>
********************************************************************************
*/

/* 头文件导入区 ------------------------------------------------------------- */

#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <SDL2/SDL.h>
#include <SDL2/SDL_image.h>


/** @defgroup MAIN MAIN
* @brief main modules
* @{
*/



/* 私有宏定义区 ------------------------------------------------------------- */

#define WIN_X_POS                               0
#define WIN_Y_POS                               0
#define WIN_WIDTH                               640
#define WIN_HIGHT                               480





/* 私有数据类型声明区 ------------------------------------------------------- */








/* 私有变量定义区 ----------------------------------------------------------- */





/** @defgroup MAIN_Exported_Variables main exported variables
* @brief 全局变量定义
* @{
*/



/** defgroup MAIN_Exported_Variables
* @}
*/





/* 私有函数定义区 ----------------------------------------------------------- */


static void outSDLError(const char * msg)
{
    fprintf(stderr, "%s error: %s\n", msg, SDL_GetError());
}
static void outSDLImgError(const char * msg)
{
    fprintf(stderr, "%s error: %s\n", msg, IMG_GetError());
}

static SDL_Texture * loadImg2Texture(const char * filepath, SDL_Renderer * sdlrd)
{
    SDL_Texture * texture = IMG_LoadTexture(sdlrd, filepath);
    if (texture == NULL)
    {
        outSDLImgError("IMG_LoadTexture()");
    }
    return texture;
}

static void renderTextureRect(SDL_Texture * tex, SDL_Renderer * sdlrd, const SDL_Rect * dst, const SDL_Rect * clip)
{
    if (dst == NULL)    return;
    SDL_RenderCopy(sdlrd, tex, clip, dst);
}

static void renderTexture(SDL_Texture * tex, SDL_Renderer * sdlrd, int x, int y, const SDL_Rect * clip)
{
    SDL_Rect dst;

    dst.x = x;
    dst.y = y;

    if (clip != NULL)
    {
        dst.w = clip->w;
        dst.h = clip->h;
    }
    else
    {
        SDL_QueryTexture(tex, NULL, NULL, &dst.w, &dst.h);
    }

    renderTextureRect(tex, sdlrd, &dst, clip);
}







/** @defgroup MAIN_Exported_Functions main exported functions
* @brief 全局函数定义
* @{
*/



/**
********************************************************************************
* @brief    简要说明
* @details  详细说明
* @param    none
* @param[in]     a: 该参数用于输入
* @param[in,out] b: 该参数用于输入和输出
* @param[out]    c: 该参数用于输出
* @retval  none
* @retval  0 函数成功
* @retval  1 函数失败
* @return  返回0成功；否则失败
* @note    none
*/
int main(int argc, char *argv[])
{
    (void) argc;
    (void) argv;

    if (SDL_Init(SDL_INIT_VIDEO) != 0)
    {
        outSDLError("SDL_Init()");
        goto initRet;
    }

    if (IMG_Init(IMG_INIT_PNG) != IMG_INIT_PNG)
    {
        outSDLImgError("IMG_Init()");
        goto initRet;
    }

    SDL_Window * sdlwin = SDL_CreateWindow("title", WIN_X_POS, WIN_Y_POS, WIN_WIDTH, WIN_HIGHT, SDL_WINDOW_SHOWN);
    if (sdlwin == NULL)
    {
        outSDLError("SDL_CreateWindow()");
        goto winRet;
    }

    SDL_Renderer * sdlrd = SDL_CreateRenderer(sdlwin, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
    if (sdlrd == NULL)
    {
        outSDLError("SDL_CreateRenderer()");
        goto renderRet;
    }


    SDL_Texture * image = loadImg2Texture("./image.png", sdlrd);
    if (image == NULL)
    {
        outSDLError("load image \"image.bmp\" failed.");
        goto textureRet;
    }


    int iW = 100, iH = 100;
    int x = (WIN_WIDTH / 2) - (iW / 2);
    int y = (WIN_HIGHT / 2) - (iH / 2);


    SDL_Rect clips[4];
    for (int i = 0; i < 4; i++)
    {
        clips[i].x = (i / 2) * iW;
        clips[i].y = (i % 2) * iH;
        clips[i].w = iW;
        clips[i].h = iH;
    }


    int useClip = 0;
    int quit = 0;
    SDL_Event e;
    while (!quit)
    {
        while (SDL_PollEvent(&e))
        {
            switch (e.type)
            {
            case SDL_QUIT:
                quit = 1;
                break;

            case SDL_KEYDOWN:
                switch (e.key.keysym.sym)
                {
                // number key 1
                case SDLK_1:
                case SDLK_KP_1:
                    useClip = 0;
                    break;

                // number key 2
                case SDLK_2:
                case SDLK_KP_2:
                    useClip = 1;
                    break;

                // number key 3
                case SDLK_3:
                case SDLK_KP_3:
                    useClip = 2;
                    break;

                // number key 4
                case SDLK_4:
                case SDLK_KP_4:
                    useClip = 3;
                    break;

                // key Esc
                case SDLK_ESCAPE:
                    quit = 1;
                    break;

                default:
                    break;
                }
                break;

            default:
                break;
            }
        }

        SDL_RenderClear(sdlrd);
        renderTexture(image, sdlrd, x, y, &clips[useClip]);
        SDL_RenderPresent(sdlrd);

        SDL_Delay(40);
    }

    SDL_DestroyTexture(image);
    SDL_DestroyRenderer(sdlrd);
    SDL_DestroyWindow(sdlwin);
    IMG_Quit();
    SDL_Quit();

    return EXIT_SUCCESS;

textureRet:
    if (image) SDL_DestroyTexture(image);
    SDL_DestroyRenderer(sdlrd);
renderRet:
    SDL_DestroyWindow(sdlwin);
winRet:
    IMG_Quit();
    SDL_Quit();
initRet:
    return EXIT_FAILURE;
}


/** defgroup MAIN_Exported_Functions
* @}
*/

/** defgroup MAIN
* @}
*/


/*********************************** END OF FILE ******************************/
